/**
 * 
 */
package jmine.tec.report.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import jmine.tec.report.DataRow;
import jmine.tec.report.ExecutableDataColumn;
import jmine.tec.report.ExecutableDataRow;
import jmine.tec.report.ExecutableDataTable;

/**
 * Simple implementation of {@link ExecutableDataTable}.
 * 
 * @author takeshi
 * @version 29/08/2007
 */
public class SimpleExecutableDataTable implements ExecutableDataTable {

    private static final long serialVersionUID = 8741513069185497133L;

    private final List<ExecutableDataColumn> columns;

    private final List<ExecutableDataRow> rows;

    /**
     * C'tor
     */
    public SimpleExecutableDataTable() {
        this(new ArrayList<ExecutableDataColumn>(), new ArrayList<ExecutableDataRow>());
    }

    /**
     * C'tor
     * 
     * @param columns the column
     * @param rows the rows
     */
    public SimpleExecutableDataTable(final List<ExecutableDataColumn> columns, final List<ExecutableDataRow> rows) {
        super();
        this.columns = columns;
        this.rows = rows;
    }

    /**
     * @param column the {@link ExecutableDataColumn}
     * @see br.com.maps.util.report.ExecutableDataTable#addColumn(br.com.maps.util.report.ExecutableDataColumn)
     */
    public final void addColumn(final ExecutableDataColumn column) {
        this.columns.add(column);
    }

    /**
     * @param row the {@link ExecutableDataRow}
     * @see br.com.maps.util.report.ExecutableDataTable#addRow(br.com.maps.util.report.ExecutableDataRow)
     */
    public final void addRow(final ExecutableDataRow row) {
        this.rows.add(row);
    }

    /**
     * @param parameters {@link Map} with parameters
     * @return {@link SimpleDataTable}
     * @see br.com.maps.util.report.ExecutableDataTable#executeAndView(java.util.Map)
     */
    public final SimpleDataTable executeAndView(final Map<String, Object> parameters) {
        this.clearCells();
        final SimpleDataTable table = new SimpleDataTable();
        for (final ExecutableDataColumn col : this.columns) {
            col.execute(this.rows, parameters);
            table.addColumn(col.getView(parameters));
        }
        for (final ExecutableDataRow row : this.rows) {
            table.addRow(row.toView());
        }
        return table;
    }

    /**
     * 
     */
    protected void clearCells() {
        for (final ExecutableDataRow row : this.rows) {
            this.clearCellsRecurse(row);
        }
    }

    /**
     * @param row the row to erase
     */
    private void clearCellsRecurse(final DataRow row) {
        row.removeAllCells();
        for (final DataRow child : row.getChildRows()) {
            this.clearCellsRecurse(child);
        }
    }

    /**
     * @param rowsToAdd the rows
     * @see br.com.maps.util.report.ExecutableDataTable#addRows(java.util.Collection)
     */
    public void addRows(final Collection<? extends ExecutableDataRow> rowsToAdd) {
        this.rows.addAll(rowsToAdd);
    }

    /**
     * @see br.com.maps.util.report.ExecutableDataTable#removeAllRows()
     */
    public void removeAllRows() {
        this.rows.clear();
    }

    /**
     * @return {@link List}
     * @see br.com.maps.util.report.ExecutableDataTable#getExecutableRows()
     */
    public List<ExecutableDataRow> getExecutableRows() {
        return new ArrayList<ExecutableDataRow>(this.rows);
    }
}
